﻿using System;
using DosTexPrj.Core.Models;
using DosTexPrj.Core.RepositoriesInterface;
using NUnit.Framework;

namespace DosTexPrj.Implement.NHibernate.Test.Repositories
{
    [TestFixture]
    public class TestKnittingOrder : RepositoryFixtureBase
    {
        private IRepository _repository;
        private DeliveryMethod _deliveryMethod;
        private PaymentMethod _paymentMethod;
        private Composition _composition;
        private OrderStatus _orderStatus;
        private FabricType _fabricType;

        protected override void Context()
        {
            this._repository = MyServiceLocator.DoGetInstance<IRepository>();
            this._deliveryMethod = this._repository.FindByKey<DeliveryMethod>(1);
            this._paymentMethod = this._repository.FindByKey<PaymentMethod>(1);
            this._composition = this._repository.FindByKey<Composition>(1);
            this._orderStatus = this._repository.FindByKey<OrderStatus>(1);
            this._fabricType = this._repository.FindByKey<FabricType>(1);
        }

        [Test]
        public void Can_Create_KnittingOrder_With_Detail()
        {
            var knittingOrder = this.SaveKnittingOrder();
            Assert.IsTrue(knittingOrder != null && knittingOrder.Id > 0
                            && knittingOrder.Details != null && knittingOrder.Details.Count > 0);
        }

        [Test]
        public void Can_Add_More_KnittingOrderDetail()
        {
            var knittingOrder = this.SaveKnittingOrder();
            knittingOrder.Details.Add(new KnittingOrderDetail
            {
                BelongToKnittingOrder = knittingOrder,
                Composition = _composition,
                Length = 2000,
                Note = "Note",
                Price = 2000,
                Weight = 2000
            });
            knittingOrder = this._repository.Save<KnittingOrder>(knittingOrder);
            Assert.IsTrue(knittingOrder != null && knittingOrder.Id > 0
                            && knittingOrder.Details != null && knittingOrder.Details.Count == 4);
        }

        [Test]
        public void Can_Delete_One_KnittingOrderDetail()
        {
            var knittingOrder = this.SaveKnittingOrder();
            knittingOrder.Details.RemoveAt(0);
            knittingOrder = this._repository.Save<KnittingOrder>(knittingOrder);
            Assert.IsTrue(knittingOrder != null && knittingOrder.Id > 0
                            && knittingOrder.Details != null && knittingOrder.Details.Count == 2);
        }

        [Test]
        public void Can_Delete_All_KnittingOrderDetail()
        {
            var knittingOrder = this.SaveKnittingOrder();
            this._repository.Delete<KnittingOrderDetail>(x => x.BelongToKnittingOrder == knittingOrder);
            knittingOrder = this._repository.FindByKey<KnittingOrder>(knittingOrder.Id);
            Assert.IsTrue(knittingOrder != null && knittingOrder.Id > 0
                            && (knittingOrder.Details == null || knittingOrder.Details.Count == 0));
        }

        [Test]
        public void Can_Create_KnittingOrderDemo()
        {
            var knittingOrder = this.SaveKnittingOrder();
            var knittingOrderDemo = new KnittingOrder();
            knittingOrderDemo.BelongToOrder = knittingOrder.BelongToOrder;
            knittingOrderDemo.BelongToSupplier = knittingOrder.BelongToSupplier;
            knittingOrderDemo.Composition = knittingOrder.Composition;
            knittingOrderDemo.DeliveryAddress = knittingOrder.DeliveryAddress;
            knittingOrderDemo.Diameter = knittingOrder.Diameter;
            knittingOrderDemo.ECRUWeight = knittingOrder.ECRUWeight;
            knittingOrderDemo.ECRUWidth = knittingOrder.ECRUWidth;
            knittingOrderDemo.FabricType = knittingOrder.FabricType;
            knittingOrderDemo.FabricWeight = knittingOrder.FabricWeight;
            knittingOrderDemo.FinishEstimatedWeight = knittingOrder.FinishEstimatedWeight;
            knittingOrderDemo.FinishEstimatedWidth = knittingOrder.FinishEstimatedWidth;
            knittingOrderDemo.Gauge = knittingOrder.Gauge;
            knittingOrderDemo.KnittingMachine = knittingOrder.KnittingMachine;
            knittingOrderDemo.BelongToKnittingOrderId = knittingOrder.Id;
            knittingOrderDemo.LenghtOfYarnPer100Needles = knittingOrder.LenghtOfYarnPer100Needles;
            knittingOrderDemo.OrderDate = DateTime.Today;
            knittingOrderDemo.OrderStatus = _orderStatus;
            knittingOrderDemo.WhaleCourse = knittingOrder.WhaleCourse;
            knittingOrderDemo = this._repository.Save<KnittingOrder>(knittingOrderDemo);
            Assert.IsTrue(knittingOrderDemo != null && knittingOrderDemo.Id > 0
                                        && knittingOrderDemo.Id != knittingOrder.Id
                                        && knittingOrderDemo.BelongToKnittingOrderId == knittingOrder.Id);
        }

        #region --- Private Methods ---

        private Order SaveOrder()
        {
            var customer = this.CreateDummyCustomer("Test KnittingOrder");
            customer = this._repository.Save<Customer>(customer);
            var order = this.CreateDummyOrder(customer, _paymentMethod, _deliveryMethod, _orderStatus);
            order = this._repository.Save<Order>(order);
            return order;
        }

        private Supplier SaveSupplier()
        {
            var supplier = this.CreateDummySupplier("Test KnittingOrder");
            supplier = this._repository.Save<Supplier>(supplier);
            return supplier;
        }

        private KnittingOrder SaveKnittingOrder()
        {
            var order = this.SaveOrder();
            var supplier = this.SaveSupplier();
            var knittingOrder = this.CreateDummyKnittingOrder(order, supplier, _orderStatus, _composition, _fabricType);
            var knittingOrderDetails = this.CreateDummyKnittingOrderDetails(knittingOrder, _composition);
            knittingOrder.Details = knittingOrderDetails;
            knittingOrder = this._repository.Save<KnittingOrder>(knittingOrder);
            return knittingOrder;
        }

        #endregion --- Private Methods ---
    }
}